package cn.iluwen.airline.Services;

import cn.iluwen.airline.Entities.Flight;
import cn.iluwen.airline.Entities.Seat;
import cn.iluwen.airline.Mapper.FlightMapper;
import cn.iluwen.airline.Mapper.SeatMapper;
import cn.iluwen.airline.utils.PageUtils;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * 航班服务类
 * 处理航班相关的业务逻辑
 */
@Service
public class FlightService {
    
    @Autowired
    private FlightMapper flightMapper;
    
    @Autowired
    private SeatMapper seatMapper;
    
    /**
     * 获取所有航班
     * @return 航班列表
     */
    public List<Flight> getAllFlights() {
        return flightMapper.findAllFlights();
    }
    
    /**
     * 分页获取所有航班
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 分页后的航班列表
     */
    public PageInfo<Flight> getFlightsWithPaging(int pageNum, int pageSize) {
        PageUtils.startPage(pageNum, pageSize);
        List<Flight> flights = flightMapper.findFlightsWithPaging();
        return PageUtils.getPageInfo(flights);
    }
    
    /**
     * 根据ID获取航班
     * @param flightId 航班ID
     * @return 航班对象
     */
    public Flight getFlightById(String flightId) {
        return flightMapper.findById(flightId);
    }
    
    /**
     * 根据多个ID获取航班列表
     * @param flightIds 航班ID列表
     * @return 航班对象列表
     */
    public List<Flight> getFlightsByIds(List<String> flightIds) {
        if (flightIds == null || flightIds.isEmpty()) {
            return new ArrayList<>();
        }
        return flightMapper.findByIds(flightIds);
    }
    
    /**
     * 根据航班号获取航班
     * @param flightNumber 航班号
     * @return 航班对象
     */
    public Flight getFlightByFlightNumber(String flightNumber) {
        return flightMapper.findByFlightNumber(flightNumber);
    }
    
    /**
     * 根据航班号关键词分页查询航班
     * @param flightNumber 航班号关键词
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 分页后的航班列表
     */
    public PageInfo<Flight> getFlightsByFlightNumberLike(String flightNumber, int pageNum, int pageSize) {
        PageUtils.startPage(pageNum, pageSize);
        List<Flight> flights = flightMapper.findByFlightNumberLike(flightNumber);
        return PageUtils.getPageInfo(flights);
    }
    
    /**
     * 根据路线查询航班
     * @param departureAirportId 出发机场ID
     * @param arrivalAirportId 到达机场ID
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 分页后的航班列表
     */
    public PageInfo<Flight> getFlightsByRoute(String departureAirportId, String arrivalAirportId, int pageNum, int pageSize) {
        PageUtils.startPage(pageNum, pageSize);
        List<Flight> flights = flightMapper.findByRoute(departureAirportId, arrivalAirportId);
        return PageUtils.getPageInfo(flights);
    }
    
    /**
     * 根据出发时间范围查询航班
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 分页后的航班列表
     */
    public PageInfo<Flight> getFlightsByDepartureTimeRange(LocalDateTime startTime, LocalDateTime endTime, int pageNum, int pageSize) {
        PageUtils.startPage(pageNum, pageSize);
        List<Flight> flights = flightMapper.findByDepartureTimeRange(startTime, endTime);
        return PageUtils.getPageInfo(flights);
    }
    
    /**
     * 添加航班
     * @param flight 航班对象
     * @return 添加后的航班对象
     */
    @Transactional
    public Flight addFlight(Flight flight) {
        // 生成UUID作为主键
        flight.setFlightId(UUID.randomUUID().toString());
        
        // 设置默认状态为"计划中"
        if (flight.getStatus() == null) {
            flight.setStatus("scheduled");
        }
        
        flightMapper.insert(flight);
        
        // 自动生成座位
        generateSeats(flight);
        
        return flight;
    }
    
    /**
     * 更新航班信息
     * @param flight 航班对象
     * @return 更新后的航班对象
     */
    public Flight updateFlight(Flight flight) {
        flightMapper.update(flight);
        return flight;
    }
    
    /**
     * 更新航班状态
     * @param flightId 航班ID
     * @param status 航班状态
     * @return 影响的行数
     */
    public int updateFlightStatus(String flightId, String status) {
        return flightMapper.updateStatus(flightId, status);
    }
    
    /**
     * 删除航班
     * @param flightId 航班ID
     * @return 是否删除成功
     */
    @Transactional
    public boolean deleteFlight(String flightId) {
        // 先删除该航班的所有座位
        seatMapper.deleteByFlightId(flightId);
        
        // 再删除航班记录
        int rows = flightMapper.delete(flightId);
        return rows > 0;
    }
    
    /**
     * 为航班生成座位
     * @param flight 航班对象
     */
    private void generateSeats(Flight flight) {
        List<Seat> seats = new ArrayList<>();
        Set<String> seatNumbers = new HashSet<>();
        
        // 经济舱座位生成（两位字母+数字）
        for (int i = 0; i < flight.getTotalEconomySeats(); i++) {
            Seat seat = new Seat();
            seat.setSeatId(UUID.randomUUID().toString());
            seat.setFlightId(flight.getFlightId());
            
            int rowNum = i / 6;
            char first = (char) ('A' + (rowNum / 26));
            char second = (char) ('A' + (rowNum % 26));
            String seatNum = "" + first + second + (i % 6 + 1);

            // 唯一性校验
            if (!seatNumbers.add(seatNum)) {
                throw new RuntimeException("经济舱座位号重复: " + seatNum);
            }
            seat.setSeatNumber(seatNum);
            seat.setSeatClass("economy");
            seat.setIsOccupied(false);
            seats.add(seat);
        }
        
        // 商务舱座位生成（B前缀+两位字母+数字）
        for (int i = 0; i < flight.getTotalBusinessSeats(); i++) {
            Seat seat = new Seat();
            seat.setSeatId(UUID.randomUUID().toString());
            seat.setFlightId(flight.getFlightId());
            
            int rowNum = i / 4;
            char first = (char) ('A' + (rowNum / 26));
            char second = (char) ('A' + (rowNum % 26));
            String seatNum = "B" + first + second + (i % 4 + 1);

            // 唯一性校验
            if (!seatNumbers.add(seatNum)) {
                throw new RuntimeException("商务舱座位号重复: " + seatNum);
            }
            seat.setSeatNumber(seatNum);
            seat.setSeatClass("business");
            seat.setIsOccupied(false);
            seats.add(seat);
        }
        
        // 批量插入座位
        if (!seats.isEmpty()) {
            seatMapper.batchInsert(seats);
        }
    }
} 